package apibasej.log;

import java.util.HashMap;
import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * http://code.google.com/p/apibasej/
 * 
 * @author Julio Azevedo Lessa - apibasej@gmail.com
 * 
 */
public class UtilLog{// extends ConfigConsumer

	public static void main(String[] args) throws InterruptedException {
		
		long t1 = System.nanoTime();
		Thread.sleep(1001);
		long t2 = System.nanoTime();
		
		System.out.println("t1: "+t1+", t2: "+t2+", M: "+getDifMilisNow(t1)+" - "+isExceeded(t1, 1000)+" - "+getDifTimeNow(t1));
	}
	
	

	
	
	private boolean ignorePrintsStart = false;
	public boolean isIgnorePrintsStart() {
		return ignorePrintsStart;
	}
	public void setIgnorePrintsStart(boolean ignorePrintsStart) {
		this.ignorePrintsStart = ignorePrintsStart;
	}

	
	
	public static final void setLevelForAllHandlers(Logger logger, Level level){
		logger.setLevel(level);
		for(Handler h : logger.getHandlers()){
			h.setLevel(level);
		}
		String m = "SET LOGGER LEVEL: LEVEL="+level.getName()+", LOGGER="+logger.getName();
		System.out.println(m);
		logger.severe("Severe OK - "+m);
		logger.warning("Warning OK - "+m);
		logger.info("Info OK - "+m);
		logger.config("Config OK - "+m);
		logger.fine("Fine OK - "+m);
		logger.finer("Finer OK - "+m);
		logger.finest("Finest OK - "+m);
	}
	
	/*
	public static final StringBuilder getStackTrace(Throwable e){
		if(e==null) return null;
		StringBuilder sb = new StringBuilder();
		sb.append(e.toString());
		sb.append('\n');
		for(StackTraceElement st : e.getStackTrace()){
			sb.append("\tat ");
			sb.append(st);
			sb.append('\n');
		}
		addCauses(sb, e);
		return sb;
	}
	
	private static final void addCauses(StringBuilder sb, Throwable e){
		Throwable cause = e.getCause();
		//if(cause==null && e instanceof XJPAException) cause = ((XJPAException)e).getCause();
		if(cause==null) return;
		sb.append("Caused by: ");
		sb.append(cause.toString());
		sb.append('\n');
		for(StackTraceElement st : cause.getStackTrace()){
			sb.append("\tat ");
			sb.append(st);
			sb.append('\n');
		}	
		addCauses(sb, cause);
	}*/
	
	
	public static final String getDifTimeNow(long nanoTimeIni){
		long n = System.nanoTime() - nanoTimeIni;
		StringBuilder sb = new StringBuilder();
		sb.append(n);
		while(sb.length()<7) sb.insert(0,'0');
		sb.insert(sb.length()-6,'.');
		//if(sb.length()>10)sb.insert(sb.length()-10,'.');
		sb.append(" mls");
		return sb.toString();
	}
	
	public static final boolean isExceeded(long nanoTimeIni, long maxTimeInMilis){
		if(getDifMilisNow(nanoTimeIni)>maxTimeInMilis) return true;
		else return false;
	}
	public static final double getDifMilisNow(long nanoTimeIni){
		double n = System.nanoTime() - nanoTimeIni;
		return n/1000000D;
	}
	
	
	private Formatter formatter;
	public Formatter getFormatter() {
		if(formatter==null){
			MySimpleLogFormater f = new MySimpleLogFormater();
			f.setShowClassAndMethod(false);
			//f.setConfig(getConfig());
			formatter = f;
		}
		return formatter;
	}

	public void setFormatter(Formatter formatter) {
		this.formatter = formatter;
	}
	
	private boolean removeConsoleHandler = false;
	public boolean isRemoveConsoleHandler() {
		return removeConsoleHandler;
	}
	public void setRemoveConsoleHandler(boolean removeConsoleHandler) {
		this.removeConsoleHandler = removeConsoleHandler;
	}

	
	public static void removeHandlers(Logger l){
		l.setUseParentHandlers(false);
		for(Handler h : l.getHandlers()){
			l.removeHandler(h);
		}
	}
	
	
	public void configMyDefaultLogger(Level level, Logger l, String patternFileLog){
		if(!isIgnorePrintsStart()){
			System.out.println("------------------------------------------------------------------------------");
			System.out.println("Configurando Logger '"+l.getName()+"' ...");
		}
		l.setUseParentHandlers(false);
		l.setLevel(level);
		if(isRemoveConsoleHandler()){
			for(Handler h : l.getHandlers()) {
				if(h instanceof ConsoleHandler) l.removeHandler(h);
			}
		}else{
			ConsoleHandler ch = null;
			for(Handler h : l.getHandlers()) {
				if(h instanceof ConsoleHandler) ch = (ConsoleHandler)h;
			}
			if(ch==null) {
				ch = new ConsoleHandler();
				l.addHandler(ch);
			}
			ch.setFormatter(getFormatter());
			ch.setLevel(level);
		}
		if(patternFileLog!=null){
			try {
				MySimpleFileHandler fh = new MySimpleFileHandler(patternFileLog);
				//fh.setConfig(getConfig());
				fh.setFormatter(getFormatter());
				fh.setLevel(level);
				l.addHandler(fh);
			} catch (Exception e) {
				String mens = "Não foi possível criar MySimpleFileHandler para o Logger '"+l.getName()+"'";
				System.out.println(mens+". Erro: "+e);
				l.log(Level.SEVERE,mens,e);
			}
		}
		if(!isIgnorePrintsStart()){
			l.severe("Severe OK");
			l.warning("Warning OK");
			l.info("Info OK");
			l.config("Config OK");
			l.fine("Fine OK");
			l.finer("Finer OK");
			l.finest("Finest OK");
			System.out.println("------------------------------------------------------------------------------");
		}
	}
	//se receber dirFileLogger==null não cria FileHandler
	//se receber pattern==null não seta o pattern nos LOGs, ex pattern: /aaaa/mysis/logs/mysis?.log
	public Logger configMyDefaultLogger(Level level, String nameLogger, String patternFileLog){
		Logger l = UtilLog.getLogger(nameLogger);
		configMyDefaultLogger(level, l, patternFileLog);
		return l;
	}
	
	// foi criado porque o Logger.getLogger não estava mantendo sempre o mesmo Logger para o mesmo nome
	private static HashMap<String,Logger> loggers;
	public static Logger getLogger(String nameLogger){
		if(loggers==null){
			loggers = new HashMap<String,Logger>();
		}
		Logger l = loggers.get(nameLogger);
		if(l==null){
			l = Logger.getLogger(nameLogger);
			loggers.put(nameLogger,l);
		}
		return l;
	}
	
	
}
